/**
  ******************************************************************************
  * @file    py32t090_hal_lpuart_ex.h
  * @author  MCU Application Team
  * @brief   Header file of LPUART HAL module.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2023 Puya Semiconductor Co.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by Puya under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __PY32T090_HAL_LPUART_EX_H
#define __PY32T090_HAL_LPUART_EX_H

#ifdef __cplusplus
extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "py32t090_hal_def.h"
#include "py32t090_hal_lpuart.h"

/** @addtogroup PY32T090_HAL_Driver
  * @{
  */

/** @addtogroup LPUARTEx
  * @{
  */

/* Exported types ------------------------------------------------------------*/
/** @defgroup LPUARTEx_Exported_Types LPUARTEx Exported Types
  * @{
  */

/**
  * @brief  LPUART wake up from stop mode parameters
  */
typedef struct
{
  uint32_t WakeUpEvent;        /*!< Specifies which event will activate the Wakeup from Stop mode flag (WUF).
                                    This parameter can be a value of @ref LPUART_WakeUp_from_Stop_Selection.
                                    If set to LPUART_WAKEUP_ON_ADDRESS, the two other fields below must
                                    be filled up. */

  uint16_t AddressLength;      /*!< Specifies whether the address is 4 or 7-bit long.
                                    This parameter can be a value of @ref LPUARTEx_WakeUp_Address_Length.  */

  uint8_t Address;             /*!< LPUART node address (7-bit long max). */
} LPUART_WakeUpTypeDef;

/**
  * @}
  */

/* Exported constants --------------------------------------------------------*/
/** @defgroup LPUARTEx_Exported_Constants LPUARTEx Exported Constants
  * @{
  */

/** @defgroup LPUARTEx_Word_Length LPUARTEx Word Length
  * @{
  */
#define LPUART_WORDLENGTH_7B          LPUART_CR1_M1   /*!< 7-bit long LPUART frame */
#define LPUART_WORDLENGTH_8B          0x00000000U     /*!< 8-bit long LPUART frame */
#define LPUART_WORDLENGTH_9B          LPUART_CR1_M0   /*!< 9-bit long LPUART frame */
/**
  * @}
  */

/** @defgroup LPUARTEx_WakeUp_Address_Length LPUARTEx WakeUp Address Length
  * @{
  */
#define LPUART_ADDRESS_DETECT_4B      0x00000000U        /*!< 4-bit long wake-up address */
#define LPUART_ADDRESS_DETECT_7B      LPUART_CR2_ADDM7   /*!< 7-bit long wake-up address */
/**
  * @}
  */

/**
  * @}
  */

/* Exported macros -----------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup LPUARTEx_Exported_Functions
  * @{
  */

/** @addtogroup LPUARTEx_Exported_Functions_Group1
  * @{
  */

/* Initialization and de-initialization functions  ****************************/
HAL_StatusTypeDef HAL_RS485Ex_Init(LPUART_HandleTypeDef *hlpuart, uint32_t Polarity, uint32_t AssertionTime,
                                   uint32_t DeassertionTime);

/**
  * @}
  */

/** @addtogroup LPUARTEx_Exported_Functions_Group2
  * @{
  */

void HAL_LPUARTEx_WakeupCallback(LPUART_HandleTypeDef *hlpuart);

/**
  * @}
  */

/** @addtogroup LPUARTEx_Exported_Functions_Group3
  * @{
  */

/* Peripheral Control functions  **********************************************/
HAL_StatusTypeDef HAL_LPUARTEx_StopModeWakeUpSourceConfig(LPUART_HandleTypeDef *hlpuart, LPUART_WakeUpTypeDef WakeUpSelection);
HAL_StatusTypeDef HAL_LPUARTEx_EnableStopMode(LPUART_HandleTypeDef *hlpuart);
HAL_StatusTypeDef HAL_LPUARTEx_DisableStopMode(LPUART_HandleTypeDef *hlpuart);

HAL_StatusTypeDef HAL_MultiProcessorEx_AddressLength_Set(LPUART_HandleTypeDef *hlpuart, uint32_t AddressLength);


/**
  * @}
  */

/**
  * @}
  */

/* Private macros ------------------------------------------------------------*/
/** @defgroup LPUARTEx_Private_Macros LPUARTEx Private Macros
  * @{
  */

/** @brief  Report the LPUART clock source.
  * @param  __HANDLE__ specifies the LPUART Handle.
  * @param  __CLOCKSOURCE__ output variable.
  * @retval LPUART clocking source, written in __CLOCKSOURCE__.
  */
#if defined (RCC_LSE_SUPPORT)
#define LPUART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)     \
  do {                                                        \
    if((__HANDLE__)->Instance == LPUART1)                     \
    {                                                         \
      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
      {                                                       \
        case RCC_LPUART1CLKSOURCE_PCLK:                       \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_PCLK;        \
          break;                                              \
        case RCC_LPUART1CLKSOURCE_LSI:                        \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_LSI;         \
          break;                                              \
        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_SYSCLK;      \
          break;                                              \
        case RCC_LPUART1CLKSOURCE_LSE:                        \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_LSE;         \
          break;                                              \
        default:                                              \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_UNDEFINED;   \
          break;                                              \
      }                                                       \
    }                                                         \
    else if((__HANDLE__)->Instance == LPUART2)                \
    {                                                         \
      switch(__HAL_RCC_GET_LPUART2_SOURCE())                  \
      {                                                       \
        case RCC_LPUART2CLKSOURCE_PCLK:                       \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_PCLK;        \
          break;                                              \
        case RCC_LPUART2CLKSOURCE_LSI:                        \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_LSI;         \
          break;                                              \
        case RCC_LPUART2CLKSOURCE_SYSCLK:                     \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_SYSCLK;      \
          break;                                              \
        case RCC_LPUART2CLKSOURCE_LSE:                        \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_LSE;         \
          break;                                              \
        default:                                              \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_UNDEFINED;   \
          break;                                              \
      }                                                       \
    }                                                         \
    else                                                      \
    {                                                         \
      (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_UNDEFINED;       \
    }                                                         \
  } while(0U)
#else
#define LPUART_GETCLOCKSOURCE(__HANDLE__,__CLOCKSOURCE__)     \
  do {                                                        \
    if((__HANDLE__)->Instance == LPUART1)                     \
    {                                                         \
      switch(__HAL_RCC_GET_LPUART1_SOURCE())                  \
      {                                                       \
        case RCC_LPUART1CLKSOURCE_PCLK:                       \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_PCLK;        \
          break;                                              \
        case RCC_LPUART1CLKSOURCE_LSI:                        \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_LSI;         \
          break;                                              \
        case RCC_LPUART1CLKSOURCE_SYSCLK:                     \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_SYSCLK;      \
          break;                                              \
        default:                                              \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_UNDEFINED;   \
          break;                                              \
      }                                                       \
    }                                                         \
    else if((__HANDLE__)->Instance == LPUART2)                \
    {                                                         \
      switch(__HAL_RCC_GET_LPUART2_SOURCE())                  \
      {                                                       \
        case RCC_LPUART2CLKSOURCE_PCLK:                       \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_PCLK;        \
          break;                                              \
        case RCC_LPUART2CLKSOURCE_LSI:                        \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_LSI;         \
          break;                                              \
        case RCC_LPUART2CLKSOURCE_SYSCLK:                     \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_SYSCLK;      \
          break;                                              \
        default:                                              \
          (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_UNDEFINED;   \
          break;                                              \
      }                                                       \
    }                                                         \
    else                                                      \
    {                                                         \
      (__CLOCKSOURCE__) = LPUART_CLOCKSOURCE_UNDEFINED;       \
    }                                                         \
  } while(0U)
#endif
/** @brief  Report the LPUART mask to apply to retrieve the received data
  *         according to the word length and to the parity bits activation.
  * @note   If PCE = 1, the parity bit is not included in the data extracted
  *         by the reception API().
  *         This masking operation is not carried out in the case of
  *         DMA transfers.
  * @param  __HANDLE__ specifies the LPUART Handle.
  * @retval None, the mask to apply to LPUART RDR register is stored in (__HANDLE__)->Mask field.
  */
#define LPUART_MASK_COMPUTATION(__HANDLE__)                           \
  do {                                                                \
    if ((__HANDLE__)->Init.WordLength == LPUART_WORDLENGTH_9B)        \
    {                                                                 \
      if ((__HANDLE__)->Init.Parity == LPUART_PARITY_NONE)            \
      {                                                               \
        (__HANDLE__)->Mask = 0x01FFU ;                                \
      }                                                               \
      else                                                            \
      {                                                               \
        (__HANDLE__)->Mask = 0x00FFU ;                                \
      }                                                               \
    }                                                                 \
    else if ((__HANDLE__)->Init.WordLength == LPUART_WORDLENGTH_8B)   \
    {                                                                 \
      if ((__HANDLE__)->Init.Parity == LPUART_PARITY_NONE)            \
      {                                                               \
        (__HANDLE__)->Mask = 0x00FFU ;                                \
      }                                                               \
      else                                                            \
      {                                                               \
        (__HANDLE__)->Mask = 0x007FU ;                                \
      }                                                               \
    }                                                                 \
    else if ((__HANDLE__)->Init.WordLength == LPUART_WORDLENGTH_7B)   \
    {                                                                 \
      if ((__HANDLE__)->Init.Parity == LPUART_PARITY_NONE)            \
      {                                                               \
        (__HANDLE__)->Mask = 0x007FU ;                                \
      }                                                               \
      else                                                            \
      {                                                               \
        (__HANDLE__)->Mask = 0x003FU ;                                \
      }                                                               \
    }                                                                 \
    else                                                              \
    {                                                                 \
      (__HANDLE__)->Mask = 0x0000U;                                   \
    }                                                                 \
  } while(0U)

/**
  * @brief Ensure that LPUART frame length is valid.
  * @param __LENGTH__ LPUART frame length.
  * @retval SET (__LENGTH__ is valid) or RESET (__LENGTH__ is invalid)
  */
#define IS_LPUART_WORD_LENGTH(__LENGTH__) (((__LENGTH__) == LPUART_WORDLENGTH_7B) || \
                                           ((__LENGTH__) == LPUART_WORDLENGTH_8B) || \
                                           ((__LENGTH__) == LPUART_WORDLENGTH_9B))

/**
  * @brief Ensure that LPUART wake-up address length is valid.
  * @param __ADDRESS__ LPUART wake-up address length.
  * @retval SET (__ADDRESS__ is valid) or RESET (__ADDRESS__ is invalid)
  */
#define IS_LPUART_ADDRESSLENGTH_DETECT(__ADDRESS__) (((__ADDRESS__) == LPUART_ADDRESS_DETECT_4B) || \
                                                     ((__ADDRESS__) == LPUART_ADDRESS_DETECT_7B))

/**
  * @}
  */

/* Private functions ---------------------------------------------------------*/

/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

#endif /* PY32T090_HAL_LPUART_EX_H */

/************************ (C) COPYRIGHT Puya *****END OF FILE******************/

